all files / src/helpers/ cards.helpers.ts

100% Statements 50/50
92.86% Branches 13/14
100% Functions 23/23
100% Lines 48/48
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127   506×   506× 506× 506×           58× 58× 40×         18×           29×         15× 68×   29×                     176×           44×                       84×     25×     18×     77×                                 25× 97×                   19×  
import * as _ from 'lodash';
import { Suit, Rank, Card } from '../game.interfaces';
 
export function createCard(pattern: string): Card {
    const CARD_PATTERN_REGEX = /([A|K|Q|J|9]|10)([♥|♦|♣|♠])/;
 
    const result = CARD_PATTERN_REGEX.exec(pattern);
    const [, rank, suit] = result;
    return result && {
        suit: suit as Suit,
        rank: rank as Rank
    };
}
 
export function createCards(Iinput: number|string[] = null): Card[] {
    if (typeof input === 'number') {
        return _.chain(createDeck())
        .shuffle()
        .sampleSize(input)
        .value();
    } else {
        return _.chain(input)
        .map(createCard)
        .value();
    }
}
 
export function hasKingAndQueen(cards: Card[]): boolean {
    return _.some(cards, {rank: Rank.King}) && _.some(cards, {rank: Rank.Queen});
}
 
export function isKingOrQueen(card: Card): boolean {
    return card.rank === Rank.King || card.rank === Rank.Queen;
}
 
export function getMarriages(cards: Card[]): Suit[] {
    return _.chain(cards)
        .groupBy(card => card.suit)
        .reduce((marriages, suitCards, suit) => {
            return hasKingAndQueen(suitCards) ? [suit, ...marriages] : marriages  
        }, [])
        .value();
}
 
export function hasMarriageOfSuit(cards: Card[], suit: Suit): boolean {
    return _.chain(getMarriages(cards))
        .includes(suit)
        .value();
}
 
export function hasMarriage(cards: Card[]): boolean {
    return getMarriages(cards).length > 0;
}
 
export function createDeck(): Card[] {
    function getDeckBySuit(suit: Suit): Card[] {
        return [
            { rank: Rank.Ace, suit }, { rank: Rank.King, suit },
            { rank: Rank.Queen, suit }, { rank: Rank.Jack, suit },
            { rank: Rank.Ten, suit }, { rank: Rank.Nine, suit }
        ];
    }
    return [
        ...getDeckBySuit(Suit.Heart),
        ...getDeckBySuit(Suit.Diamond),
        ...getDeckBySuit(Suit.Club),
        ...getDeckBySuit(Suit.Spade)
    ];
}
 
export function createShuffledDeck(): Card[] {
    return _.chain(createDeck())
        .shuffle()
        .value();
}
 
export function getCard(cards: Card[], card: Card): Card {
    return _.find(cards, ({suit, rank}) => card.suit === suit && card.rank === rank);
}
 
export function cardExistsIn(cards: Card[], card: Card): boolean {
    return !!getCard(cards, card);
}
 
export function hasEightCards(cards: Card[]): boolean {
    return cards.length === 8;
}
 
export function getPointsByCard(card: Card): number {
    return {
        [Rank.Ace]: 11,
        [Rank.King]: 4,
        [Rank.Queen]: 3,
        [Rank.Jack]: 2,
        [Rank.Ten]: 10,
        [Rank.Nine]: 0,
    }[card.rank];
}
 
export function getTrumpPointsBySuit(suit: Suit): number {
    return {
        [Suit.Heart]: 100,
        [Suit.Diamond]: 80,
        [Suit.Club]: 60,
        [Suit.Spade]: 40
    }[suit];
}
 
export function getCardsByColor(cards: Card[], color: Suit): Card[] {
    return _.chain(cards)
        .filter((card: Card) => card.suit === color)
        .value();
}
 
export function cardsWithSpecificColorExists(cards: Card[], color: Suit): boolean {
    return getCardsByColor(cards, color).length > 0;
}
 
export function getCardWithHighestRank(cards: Card[]): Card {
    return _.chain(cards)
        .maxBy(getPointsByCard)
        .value();
}
 
export function areCardsEqual(card1: Card, card2: Card): boolean {
    return _.eq(card1, card2);
}